{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# अंश 2: फेडरेटेड लर्निंग (Federated Learning) में परिचय\n",
    "\n",
    "अंतिम खंड में, हमने Pointer Tensor के बारे में सीखा, जो कि डीप लर्निंग (Deep Learning) को सुरक्षित रखने के लिए हमें आवश्यक बुनियादी ढाँचे का निर्माण करते हैं। इस खंड में, हम यह देखने के लिए जा रहे हैं कि कैसे इन बुनियादी उपकरणों का उपयोग करके हमारी पहली गोपनीयता को लागू करने के लिए डीप लर्निंग (Deep Learning) algorithm, फेडरेटेड लर्निंग (Federated Learning) को संरक्षित किया जाए।\n",
    "\n",
    "लेखक:\n",
    "- Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
    "\n",
    "अनुवादक:\n",
    "- Arkadip Bhattacharya - Github: [@darkmatter18](https://github.com/darkmatter18)\n",
    "\n",
    "### फेडरेटेड लर्निंग (Federated Learning) क्या है?\n",
    "\n",
    "यह डीप लर्निंग (Deep Learning) मॉडल को प्रशिक्षित करने का एक सरल, शक्तिशाली तरीका है। यदि आप प्रशिक्षण डेटा (Training Data) के बारे में सोचते हैं, तो यह हमेशा किसी प्रकार की संग्रह प्रक्रिया का परिणाम होता है। लोग (उपकरणों के माध्यम से) वास्तविक दुनिया में घटनाओं को रिकॉर्ड करके डेटा उत्पन्न करते हैं। \n",
    "आम तौर पर, यह डेटा एक, केंद्रीय स्थान पर एकत्रित होता है ताकि आप मशीन लर्निंग मॉडल (Machine Learniing Model) को प्रशिक्षित (train) कर सकें। Federated Learning इसे अपने सिर पर रखता है!\n",
    "\n",
    "मॉडल में प्रशिक्षण डेटा (Training Data) लाने के बजाय (एक केंद्रीय सर्वर), आप मॉडल (Model) को प्रशिक्षण डेटा (Training Data) में लाते हैं (जहाँ भी रहते हैं)\n",
    "\n",
    "विचार यह है कि यह जो कोई भी डेटा को केवल स्थायी प्रतिलिपि बनाने के लिए अनुमति देता है, और इस प्रकार उस पर नियंत्रण बनाए रखता है जिसके पास इसकी पहुंच है। \n",
    "\n",
    "बहुत अच्छा, नाह (Pretty cool, eh)?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# अनुभाग 2.1 - एक खिलौना फेडरेटेड लर्निंग (Federated Learning) उदाहरण\n",
    "\n",
    "चलो एक खिलौना मॉडल को केंद्रीकृत तरीके से प्रशिक्षित करके शुरू करें। यह एक साधारण मॉडल के रूप में मिलता है। हमें पहले चाहिए:\n",
    "\n",
    "- एक खिलौना डाटासेट (a toy dataset)\n",
    "- एक मॉडल (a model)\n",
    "- डेटा को फिट करने के लिए एक मॉडल को प्रशिक्षित करने के लिए कुछ बुनियादी प्रशिक्षण तर्क (some basic training logic for training a model to fit the data.)।\n",
    "\n",
    "नोट: यदि यह API आपके लिए परिचित नहीं है - तो [fast.ai](http://fast.ai) पर जाएं और इस ट्यूटोरियल को जारी रखने से पहले अपना कोर्स कर लें।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "from torch import optim"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# A Toy Dataset\n",
    "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)\n",
    "target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)\n",
    "\n",
    "# A Toy Model\n",
    "model = nn.Linear(2,1)\n",
    "\n",
    "def train():\n",
    "    # Training Logic\n",
    "    opt = optim.SGD(params=model.parameters(),lr=0.1)\n",
    "    for iter in range(20):\n",
    "\n",
    "        # 1) erase previous gradients (if they exist)\n",
    "        opt.zero_grad()\n",
    "\n",
    "        # 2) make a prediction\n",
    "        pred = model(data)\n",
    "\n",
    "        # 3) calculate how much we missed\n",
    "        loss = ((pred - target)**2).sum()\n",
    "\n",
    "        # 4) figure out which weights caused us to miss\n",
    "        loss.backward()\n",
    "\n",
    "        # 5) change those weights\n",
    "        opt.step()\n",
    "\n",
    "        # 6) print our progress\n",
    "        print(loss.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "आखिर तुमने इसे हासिल कर ही लिया है! हमने पारंपरिक तरीके से एक बुनियादी मॉडल को प्रशिक्षित किया है। हमारे सभी डेटा को हमारी स्थानीय मशीन में एकत्रित किया जाता है और हम इसका उपयोग अपने मॉडल में अपडेट करने के लिए कर सकते हैं। फेडरेटेड लर्निंग (Federated Learning), हालांकि, इस तरह से काम नहीं करता है। तो, आइए इस उदाहरण को संशोधित करते हुए इसे Federated Learning way के रूप में करें!\n",
    "\n",
    "\n",
    "तो, हमें क्या चाहिए:\n",
    "\n",
    "- कुछ कार्यकर्ता (workers) बनाएँ\n",
    "- प्रत्येक कार्यकर्ता पर प्रशिक्षण डेटा (Training Data) का Pointer प्राप्त करें\n",
    "- अद्यतन प्रशिक्षण federated learning करने के लिए\n",
    "\n",
    "    नए प्रशिक्षण कदम:\n",
    "    - सही कार्यकर्ता (worker) में मॉडल भेजें\n",
    "    - वहां स्थित डेटा पर ट्रेन करें\n",
    "    - मॉडल वापस प्राप्त करें और अगले कार्यकर्ता (Worker) के साथ दोहराएं"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import syft as sy\n",
    "hook = sy.TorchHook(torch)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a couple workers\n",
    "\n",
    "bob = sy.VirtualWorker(hook, id=\"bob\")\n",
    "alice = sy.VirtualWorker(hook, id=\"alice\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A Toy Dataset\n",
    "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)\n",
    "target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)\n",
    "\n",
    "# get pointers to training data on each worker by\n",
    "# sending some training data to bob and alice\n",
    "data_bob = data[0:2]\n",
    "target_bob = target[0:2]\n",
    "\n",
    "data_alice = data[2:]\n",
    "target_alice = target[2:]\n",
    "\n",
    "# Iniitalize A Toy Model\n",
    "model = nn.Linear(2,1)\n",
    "\n",
    "data_bob = data_bob.send(bob)\n",
    "data_alice = data_alice.send(alice)\n",
    "target_bob = target_bob.send(bob)\n",
    "target_alice = target_alice.send(alice)\n",
    "\n",
    "# organize pointers into a list\n",
    "datasets = [(data_bob,target_bob),(data_alice,target_alice)]\n",
    "\n",
    "opt = optim.SGD(params=model.parameters(),lr=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train():\n",
    "    # Training Logic\n",
    "    opt = optim.SGD(params=model.parameters(),lr=0.1)\n",
    "    for iter in range(10):\n",
    "        \n",
    "        # NEW) iterate through each worker's dataset\n",
    "        for data,target in datasets:\n",
    "            \n",
    "            # NEW) send model to correct worker\n",
    "            model.send(data.location)\n",
    "\n",
    "            # 1) erase previous gradients (if they exist)\n",
    "            opt.zero_grad()\n",
    "\n",
    "            # 2) make a prediction\n",
    "            pred = model(data)\n",
    "\n",
    "            # 3) calculate how much we missed\n",
    "            loss = ((pred - target)**2).sum()\n",
    "\n",
    "            # 4) figure out which weights caused us to miss\n",
    "            loss.backward()\n",
    "\n",
    "            # 5) change those weights\n",
    "            opt.step()\n",
    "            \n",
    "            # NEW) get model (with gradients)\n",
    "            model.get()\n",
    "\n",
    "            # 6) print our progress\n",
    "            print(loss.get()) # NEW) slight edit... need to call .get() on loss\\\n",
    "    \n",
    "# federated averaging"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## बहुत बढ़िया!\n",
    "\n",
    "तथा देखा (And voilà!)\n",
    "\n",
    "अब हम फेडरेटेड लर्निंग (Federated Learning) का उपयोग करके एक बहुत ही सरल डीप लर्निंग मॉडल (Deep Learning Model) का प्रशिक्षण ले रहे हैं! हम प्रत्येक कार्यकर्ता को मॉडल भेजते हैं, एक नया ग्रेडिएंट उत्पन्न करते हैं, और फिर ग्रेडिएंट को हमारे स्थानीय सर्वर पर वापस लाते हैं, जहाँ हम अपने ग्लोबल मॉडल को अपडेट करते हैं। इस प्रक्रिया में कभी भी हम अंतर्निहित प्रशिक्षण डेटा तक पहुंच नहीं देखते या अनुरोध नहीं करते हैं! हम बॉब (Bob) और ऐलिस (Alice) की गोपनीयता को बचाते हैं !!!\n",
    "\n",
    "## इस उदाहरण की कमियाँ\n",
    "\n",
    "इसलिए, जबकि यह उदाहरण फेडरेटेड लर्निंग का एक अच्छा परिचय है, इसमें अभी भी कुछ बड़ी कमियां हैं। सबसे विशेष रूप से, जब हम `model.get()` कहते हैं और बॉब या ऐलिस से अपडेटेड मॉडल प्राप्त करते हैं, तो हम वास्तव में बॉब और ऐलिस के प्रशिक्षण डेटा के बारे में बहुत कुछ सीख सकते हैं। कुछ मामलों में, हम उनके प्रशिक्षण डेटा को पूरी तरह से बहाल कर सकते हैं!\n",
    "\n",
    "तो, क्या करना है? वैसे, लोगों को रोजगार देने वाली पहली रणनीति केंद्रीय सर्वर (Central Server) पर अपलोड करने से पहले कई व्यक्तियों में ग्रेडिएंट का औसत है। हालाँकि, इस रणनीति को Pointer Tensor वस्तुओं के कुछ और परिष्कृत उपयोग की आवश्यकता होगी। इसलिए, अगले भाग में, हम अधिक उन्नत Pointer कार्यक्षमता के बारे में जानने के लिए कुछ समय लेने जा रहे हैं और फिर हम इस फेडरेटेड लर्निंग उदाहरण को अपग्रेड करेंगे\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# बधाई हो!!! - समुदाय में शामिल होने का समय!\n",
    "\n",
    "इस नोटबुक ट्यूटोरियल को पूरा करने पर बधाई! यदि आपने इसका आनंद लिया है और एआई और एआई आपूर्ति श्रृंखला (डेटा) के विकेन्द्रीकृत स्वामित्व के संरक्षण की ओर आंदोलन में शामिल होना चाहते हैं, तो आप निम्न तरीकों से ऐसा कर सकते हैं!\n",
    "\n",
    "### Pysyft को Github पर Star करें!\n",
    "\n",
    "हमारे समुदाय की मदद करने का सबसे आसान तरीका GitHub repos अभिनीत है! यह हमारे द्वारा बनाए जा रहे कूल टूल्स के बारे में जागरूकता बढ़ाने में मदद करता है।\n",
    "\n",
    "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### हमारी Slack में शामिल हों!\n",
    "\n",
    "नवीनतम प्रगति पर अद्यतित रहने का सबसे अच्छा तरीका हमारे समुदाय में शामिल होना है! आप फॉर्म भरकर ऐसा कर सकते हैं। [http://slack.openmined.org](http://slack.openmined.org)\n",
    "\n",
    "### एक कोड प्रोजेक्ट में शामिल हों!\n",
    "\n",
    "हमारे समुदाय में योगदान करने का सबसे अच्छा तरीका एक कोड योगदानकर्ता बनना है! किसी भी समय आप PySyft GitHub Issues जारी करने वाले पृष्ठ पर जा सकते हैं और \"प्रोजेक्ट्स\" के लिए फ़िल्टर कर सकते हैं। यह आपको सभी शीर्ष स्तर के टिकट दिखाएगा कि आप किन परियोजनाओं में शामिल हो सकते हैं! यदि आप किसी परियोजना में शामिल नहीं होना चाहते हैं, लेकिन आप थोड़ी सी कोडिंग करना चाहते हैं, तो आप \"अच्छा पहला अंक\" चिह्नित गीथहब मुद्दों की खोज करके अधिक \"वन ऑफ़\" मिनी-प्रोजेक्ट्स की तलाश कर सकते हैं।\n",
    "\n",
    "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### दान करना\n",
    "\n",
    "यदि आपके पास हमारे कोडबेस में योगदान करने का समय नहीं है, लेकिन फिर भी समर्थन उधार देना चाहते हैं, तो आप हमारे ओपन कलेक्टिव में भी एक बैकर बन सकते हैं। सभी दान हमारी वेब होस्टिंग और अन्य सामुदायिक खर्चों जैसे कि हैकाथॉन और मीटअप की ओर जाते हैं!\n",
    "\n",
    "[OpenMined's Open Collective Page](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}